﻿using System;
using System.Data.SQLite;

namespace Amgine
{
    interface ITypeKeeper
    {
        int Type { get; set; }
        string getTypeString();
    }

    abstract class BaseEntity
    {
        public BaseEntity()
        {
            ID = -1;
        }

        public string TableName { get; set; }
        public int ID { get; set; }
        
        public abstract bool createOrUpdate();

        public bool delete()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(
                    " DELETE FROM " + TableName + " WHERE " + DBHelper.PKID + " = " + ID + " ; ",
                DBHelper.BASE_SQLITE_CONNECTION);
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class Account : BaseEntity
    {
        public string Title { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public string Remark { get; set; }
        public int GroupId { get; set; }

        public Account() : base()
        {
            Title = "";
            Name = "";
            Password = "";
            Remark = "";
            GroupId = -1;
            TableName = DBHelper.TABLE_ACCOUNT;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_ACCOUNT
                        + " VALUES (NULL,@title,@name,@psw,@remark,@group); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_ACCOUNT + " SET "
                        + DBHelper.ACCOUNT_GROUP_ID + " =@group, "
                        + DBHelper.ACCOUNT_TITLE + " =@title, "
                        + DBHelper.ACCOUNT_NAME + " =@name, "
                        + DBHelper.ACCOUNT_PASSWORD + " =@psw, "
                        + DBHelper.ACCOUNT_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@group", GroupId),
                    new SQLiteParameter("@title", EncryptDecryptUtils.DES3Encrypt(Title, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@name", EncryptDecryptUtils.DES3Encrypt(Name, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@psw", EncryptDecryptUtils.DES3Encrypt(Password, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@remark", EncryptDecryptUtils.DES3Encrypt(Remark, EncryptDecryptUtils.GLOBAL_INIT_VAR))
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class AccountGroup : BaseEntity
    {
        public string Title { get; set; }
        public string Remark { get; set; }

        public AccountGroup() : base()
        {
            Title = "";
            Remark = "";
            TableName = DBHelper.TABLE_ACCOUNT_GROUP;
        }

        public bool delete(bool isDeleteChild)
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(
                    " DELETE FROM " + DBHelper.TABLE_ACCOUNT_GROUP
                    + " WHERE " + DBHelper.PKID + " = " + ID + " ; ",
                DBHelper.BASE_SQLITE_CONNECTION);
                ret += cmd.ExecuteNonQuery();

                if (isDeleteChild)
                {
                    cmd.CommandText = " DELETE FROM " + DBHelper.TABLE_ACCOUNT
                                + " WHERE " + DBHelper.ACCOUNT_GROUP_ID + " = " + ID + " ; ";
                    ret += cmd.ExecuteNonQuery();
                }
                tran.Commit();
            }
            return ret != 0;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_ACCOUNT_GROUP
                        + " VALUES (NULL,@title,@remark); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_ACCOUNT_GROUP + " SET "
                        + DBHelper.ACCOUNT_GROUP_TITLE + " =@title, "
                        + DBHelper.ACCOUNT_GROUP_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@title", EncryptDecryptUtils.DES3Encrypt(Title,EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@remark", EncryptDecryptUtils.DES3Encrypt(Remark,EncryptDecryptUtils.GLOBAL_INIT_VAR))
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class Dictionary : BaseEntity, ITypeKeeper
    {
        public const int TYPE_OTHERS = 0;
        public const int TYPE_ACCOUNT = 1;
        public const int TYPE_PASSWORD = 2;
        public const int TYPE_LINKMAN = 3;
        public const int TYPE_LINKMAN_DETAILS = 4;
        public const int TYPE_NOTE = 5;
        public const int TYPE_TOOLS = 6;

        public int Type { get; set; }
        public string Code { get; set; }
        public string Info { get; set; }
        public bool IsEncrypted { get; set; }

        public Dictionary() : base()
        {
            Type = 0;
            Code = "";
            Info = "";
            IsEncrypted = false;
            TableName = DBHelper.TABLE_DICTIONARY;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_DICTIONARY
                        + " VALUES (NULL,@type,@code,@info,@flag); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_DICTIONARY + " SET "
                        + DBHelper.DICTIONARY_TYPE + " =@type, "
                        + DBHelper.DICTIONARY_CODE + " =@code, "
                        + DBHelper.DICTIONARY_INFO + " =@info, "
                        + DBHelper.DICTIONARY_IS_ENCRYPTED + " =@flag "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@code", (IsEncrypted ? EncryptDecryptUtils.DES3Encrypt(Code, EncryptDecryptUtils.GLOBAL_INIT_VAR) : Code)),
                    new SQLiteParameter("@info", (IsEncrypted ? EncryptDecryptUtils.DES3Encrypt(Info, EncryptDecryptUtils.GLOBAL_INIT_VAR) : Info)),
                    new SQLiteParameter("@type", Type),
                    new SQLiteParameter("@flag", IsEncrypted)
                });

                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }

            return ret != 0;
        }

        public string getTypeString()
        {
            string str = "其它";
            switch (Type)
            {
                case TYPE_OTHERS: break;
                case TYPE_ACCOUNT:
                    str = "账号";
                    break;
                case TYPE_PASSWORD:
                    str = "密码";
                    break;
                case TYPE_LINKMAN:
                    str = "联系人";
                    break;
                case TYPE_LINKMAN_DETAILS:
                    str = "联系方式";
                    break;
                case TYPE_NOTE:
                    str = "文本";
                    break;
                case TYPE_TOOLS:
                    str = "应用平台";
                    break;
                default: break;
            }
            return str;
        }
    }

    class Linkman : BaseEntity
    {
        public string Name { get; set; }
        public string Remark { get; set; }
        public int GroupId { get; set; }

        public Linkman() : base()
        {
            Name = "";
            Remark = "";
            GroupId = -1;
            TableName = DBHelper.TABLE_LINKMAN;
        }

        public bool delete(bool isDeleteChild)
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(
                    " DELETE FROM " + DBHelper.TABLE_LINKMAN
                    + " WHERE " + DBHelper.PKID + " = " + ID + " ; ",
                DBHelper.BASE_SQLITE_CONNECTION);
                ret += cmd.ExecuteNonQuery();

                if (isDeleteChild)
                {
                    cmd.CommandText = " DELETE FROM " + DBHelper.TABLE_LINKMAN_DETAILS
                                + " WHERE " + DBHelper.LINKMAN_ID + " = " + ID + " ; ";
                    ret += cmd.ExecuteNonQuery();
                }
                tran.Commit();
            }
            return ret != 0;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_LINKMAN
                        + " VALUES (NULL,@group,@name,@remark); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_LINKMAN + " SET "
                        + DBHelper.LINKMAN_GROUP_ID + " =@group, "
                        + DBHelper.LINKMAN_NAME + " =@name, "
                        + DBHelper.LINKMAN_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@group", GroupId),
                    new SQLiteParameter("@name", EncryptDecryptUtils.DES3Encrypt(Name, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@remark", EncryptDecryptUtils.DES3Encrypt(Remark, EncryptDecryptUtils.GLOBAL_INIT_VAR))
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class LinkmanGroup : BaseEntity
    {
        public string Name { get; set; }
        public string Remark { get; set; }

        public LinkmanGroup() : base()
        {
            Name = "";
            Remark = "";
            TableName = DBHelper.TABLE_LINKMAN_GROUP;
        }

        public bool delete(bool isDeleteChild, bool isDeleteGrandchild)
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(
                    " DELETE FROM " + DBHelper.TABLE_LINKMAN_GROUP
                    + " WHERE " + DBHelper.PKID + " = " + ID + " ; ",
                DBHelper.BASE_SQLITE_CONNECTION);
                ret += cmd.ExecuteNonQuery();

                if (isDeleteGrandchild)
                {
                    cmd.CommandText = " DELETE FROM " + DBHelper.TABLE_LINKMAN_DETAILS
                                + " WHERE " + DBHelper.LINKMAN_ID + " IN(SELECT "
                                + DBHelper.PKID + " FROM " + DBHelper.TABLE_LINKMAN
                                + " WHERE " + DBHelper.LINKMAN_GROUP_ID + " = "
                                + DBHelper.PKID + " ); ";
                    ret += cmd.ExecuteNonQuery();
                }

                if (isDeleteChild)
                {
                    cmd.CommandText = " DELETE FROM " + DBHelper.TABLE_LINKMAN
                                + " WHERE " + DBHelper.LINKMAN_GROUP_ID + " = " + ID + " ; ";
                    ret += cmd.ExecuteNonQuery();
                }

                tran.Commit();
            }
            return ret != 0;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO "
                        + DBHelper.TABLE_LINKMAN_GROUP
                        + " VALUES (NULL,@name,@remark); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_LINKMAN_GROUP + " SET "
                        + DBHelper.LINKMAN_GROUP_NAME + " =@name, "
                        + DBHelper.LINKMAN_GROUP_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@name", EncryptDecryptUtils.DES3Encrypt(Name, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@remark", EncryptDecryptUtils.DES3Encrypt(Remark, EncryptDecryptUtils.GLOBAL_INIT_VAR))
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class LinkmanDetails : BaseEntity, ITypeKeeper
    {
        public const int TYPE_OTHERS = 0;
        public const int TYPE_PHONE = 1;
        public const int TYPE_EMAIL = 2;

        public int Type { get; set; }
        public string Info { get; set; }
        public string Remark { get; set; }
        public int LinkmanId { get; set; }

        public LinkmanDetails() : base()
        {
            Type = 0;
            Info = "";
            Remark = "";
            LinkmanId = -1;
            TableName = DBHelper.TABLE_LINKMAN_DETAILS;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_LINKMAN_DETAILS
                        + " VALUES (NULL,@type,@info,@remark,@linkman); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_LINKMAN_DETAILS + " SET "
                        + DBHelper.LINKMAN_ID + " =@linkman, "
                        + DBHelper.LINKMAN_DETAILS_TYPE + " =@type, "
                        + DBHelper.LINKMAN_DETAILS_INFO + " =@info, "
                        + DBHelper.LINKMAN_DETAILS_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@linkman", LinkmanId),
                    new SQLiteParameter("@type", Type),
                    new SQLiteParameter("@info", EncryptDecryptUtils.DES3Encrypt(Info, EncryptDecryptUtils.GLOBAL_INIT_VAR)),
                    new SQLiteParameter("@remark", EncryptDecryptUtils.DES3Encrypt(Remark, EncryptDecryptUtils.GLOBAL_INIT_VAR))
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }

        public string getTypeString()
        {
            string str = "其它";
            switch (Type)
            {
                case TYPE_OTHERS: break;
                case TYPE_PHONE:
                    str = "电话";
                    break;
                case TYPE_EMAIL:
                    str = "邮箱";
                    break;
                default: break;
            }
            return str;
        }
    }

    class Note : BaseEntity
    {
        public string Title { get; set; }
        public string Info { get; set; }
        public string CreateTime { get; set; }
        public string UpdateTime { get; set; }

        public Note() : base()
        {
            Title = "";
            Info = "";
            CreateTime = "";
            UpdateTime = "";
            TableName = DBHelper.TABLE_NOTE;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    CreateTime = DateTime.Now.ToString();
                    UpdateTime = CreateTime;
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_NOTE
                        + " VALUES (NULL,@title,@info,@ct,@ut); ";
                }
                else
                {
                    UpdateTime = DateTime.Now.ToString();
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_NOTE + " SET "
                        + DBHelper.NOTE_TITLE + " =@title, "
                        + DBHelper.NOTE_INFO + " =@info, "
                        + DBHelper.NOTE_CREATE_TIME + " =@ct, "
                        + DBHelper.NOTE_UPDATE_TIME + " =@ut "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@title", Title),
                    new SQLiteParameter("@info", Info),
                    new SQLiteParameter("@ct", CreateTime),
                    new SQLiteParameter("@ut", UpdateTime)
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class Tool : BaseEntity
    {
        public string Name { get; set; }
        public string Remark { get; set; }
        public int GroupId { get; set; }

        public Tool() : base()
        {
            Name = "";
            Remark = "";
            GroupId = -1;
            TableName = DBHelper.TABLE_TOOL;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_TOOL
                        + " VALUES (NULL,@name,@remark,@group); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_TOOL + " SET "
                        + DBHelper.TOOL_GROUP_ID + " =@group, "
                        + DBHelper.TOOL_NAME + " =@name, "
                        + DBHelper.TOOL_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@group", GroupId),
                    new SQLiteParameter("@name", Name),
                    new SQLiteParameter("@remark", Remark)
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }

    class ToolGroup : BaseEntity
    {
        public string Title { get; set; }
        public string Remark { get; set; }

        public ToolGroup() : base()
        {
            Title = "";
            Remark = "";
            TableName = DBHelper.TABLE_TOOL_GROUP;
        }

        public bool delete(bool isDeleteChild)
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(
                    " DELETE FROM " + DBHelper.TABLE_TOOL_GROUP
                    + " WHERE " + DBHelper.PKID + " = " + ID + " ; ",
                DBHelper.BASE_SQLITE_CONNECTION);
                ret += cmd.ExecuteNonQuery();

                if (isDeleteChild)
                {
                    cmd.CommandText = " DELETE FROM " + DBHelper.TABLE_TOOL
                                + " WHERE " + DBHelper.TOOL_GROUP_ID + " = " + ID + " ; ";
                    ret += cmd.ExecuteNonQuery();
                }
                tran.Commit();
            }
            return ret != 0;
        }

        public override bool createOrUpdate()
        {
            int ret = 0;
            using (SQLiteTransaction tran = DBHelper.BASE_SQLITE_CONNECTION.BeginTransaction())
            {
                SQLiteCommand cmd = new SQLiteCommand(DBHelper.BASE_SQLITE_CONNECTION);
                if (ID == -1)
                {
                    cmd.CommandText = " INSERT INTO " + DBHelper.TABLE_TOOL_GROUP
                        + " VALUES (NULL,@title,@remark); ";
                }
                else
                {
                    cmd.CommandText = " UPDATE "
                        + DBHelper.TABLE_TOOL_GROUP + " SET "
                        + DBHelper.TOOL_GROUP_TITLE + " =@title, "
                        + DBHelper.TOOL_GROUP_REMARK + " =@remark "
                        + " WHERE " + DBHelper.PKID + " =@id; ";
                }

                cmd.Parameters.AddRange(new[] {
                    new SQLiteParameter("@id", ID),
                    new SQLiteParameter("@title", Title),
                    new SQLiteParameter("@remark", Remark)
                });
                ret = cmd.ExecuteNonQuery();
                tran.Commit();
            }
            return ret != 0;
        }
    }
}
